/*
@STI LICENSE
(C) 2006-2008 Universit�t Innsbruck.

This file is part of myOntology.

myOntologyis free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

myOntologyis distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with myOntology.  If not, see <http://www.gnu.org/licenses/>.

@STI LICENSE */
package controller.sesameDataConnector;

import java.util.ArrayList;
import java.util.Date;

import model.Vocabulary;
import model.dataContainer.ChangerequestContainer;

import org.apache.log4j.Logger;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.impl.LiteralImpl;
import org.openrdf.model.impl.URIImpl;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryResult;

public class ChangerequestConnector {

	public static Logger logger = Logger.getLogger(ChangerequestConnector.class);
	
	public static URI insert(ChangerequestContainer cr, String elementId) {
		int i=0;
		URI id = new URIImpl(Vocabulary.NAMESPACE + elementId + "/ChangeRequest/" + Long.toString(cr.getId().getTime()));
		try {
			
			RepositoryConnection con = AbstractDataConnector.getConnection();
			
			
			//while (i < 10 || con.getStatements(id, null, null, false) != null) {
			//	id = new URIImpl(Vocabulary.NAMESPACE + elementId + "/ChangeRequest/" + Long.toString(cr.getId().getTime()));
			//	i++;
			//}
			
			if (i == 10) 
				return null;
			
			try {
				con.add(id, RDF.TYPE, Vocabulary.CHANGEREQUEST);
				con.add(id, RDFS.LABEL, new LiteralImpl(cr.getLable()));
				con.add(id, RDFS.COMMENT, new LiteralImpl(cr.getComment()));
				con.add(id, Vocabulary.ISCHANGEREQUESTFOR, cr.getElement());
				con.add(id, Vocabulary.HASSTATE, cr.getState());
				con.add(id, Vocabulary.HASUSERID, cr.getUserid());
				
				con.commit();
			} catch( Exception e ) {
				con.rollback();	
				throw e;
			} finally {
				con.close();
			}
			
		} catch (Exception e){
			logger.error(e);
		}	
		return id;
	}
	
	public static ChangerequestContainer select(URI id) {
		ChangerequestContainer cr = new ChangerequestContainer();
		Statement st;
		
		
		cr.setId(new Date(Long.valueOf(id.getLocalName())));
		
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			
			try {
				
				RepositoryResult<Statement> statements = con.getStatements(id, RDFS.LABEL, null, false);				
				try {
					if (statements.hasNext()) {
						st = statements.next();
						cr.setLable(st.getObject().stringValue());
					}

				} finally {
					statements.close();			
				}

				statements = con.getStatements(id, RDFS.COMMENT, null, false);
				try {
					if (statements.hasNext()) {
						st = statements.next();
						cr.setComment(st.getObject().stringValue());
					}

				} finally {
					statements.close();			
				}

				statements = con.getStatements(id, Vocabulary.ISCHANGEREQUESTFOR, null, false);
				try {
					if (statements.hasNext()) {
						st = statements.next();
						cr.setElement( (URI)st.getObject() );
					}

				} finally {
					statements.close();			
				}

				statements = con.getStatements(id, Vocabulary.HASSTATE, null, false);
				try {
					if (statements.hasNext()) {
						st = statements.next();
						cr.setState( (URI)st.getObject() );
					}

				} finally {
					statements.close();			
				}

				statements = con.getStatements(id, Vocabulary.HASUSERID, null, false);
				try {
					if (statements.hasNext()) {
						st = statements.next();
						cr.setUserid( (URI)st.getObject() );
					}
				
				} finally {
					statements.close();			
				}
				
			}finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
			return null;
		}
		
		return cr;
	}
		
	
	public static boolean openChangeState(URI uri) {

		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			try {
				con.remove( uri, Vocabulary.HASSTATE, null );
				con.add(uri, Vocabulary.HASSTATE, Vocabulary.REQUESTSTATEREOPENED);
				
				con.commit();
			} catch( Exception e ) {
				con.rollback();	
				throw e;
			} finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
			return false;
		}
		return true;
	}
	
	
	public static boolean isOpen(URI uri) {
		boolean ret = false;
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			try {
				RepositoryResult<Statement> statements = con.getStatements(uri, Vocabulary.HASSTATE, null, false);
				try {
					if (statements.hasNext()) {
						String tmp = statements.next().getObject().stringValue();
						if (tmp.equals(Vocabulary.REQUESTSTATEOPEN.stringValue()) || tmp.equals(Vocabulary.REQUESTSTATEREOPENED.stringValue()))
							ret = true;
					}
				} finally {
					statements.close();
				}
			} finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
			return false;
		}
		return ret;
	}
	
	public static boolean closeChangeState(URI uri) {
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			try {
				con.remove(uri, Vocabulary.HASSTATE, null);				
				con.add(uri, Vocabulary.HASSTATE, Vocabulary.REQUESTSTATECLOSED);
				
				con.commit();
			} catch( Exception e ) {
				con.rollback();	
				throw e;
			} finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
			return false;
		}
		return true;
	}
	
	public static ArrayList<ChangerequestContainer> selectAllOfElement(URI elementId) {
	
		ArrayList<ChangerequestContainer> cr = new ArrayList<ChangerequestContainer>();
		Statement st;
		
		
		try {
			RepositoryConnection con = AbstractDataConnector.getConnection();
			
			try {
				RepositoryResult<Statement> statements = con.getStatements(null, Vocabulary.ISCHANGEREQUESTFOR, elementId, false);
				try {
					while (statements.hasNext()) {
						st = statements.next();
						cr.add(select( (URI)st.getSubject() ));
					}	

				} finally {
					statements.close();			
				}
				
			}finally {
				con.close();
			}
		} catch (Exception e) {
			logger.error(e);
			return null;
		}
		
		return cr;
	}

	
}
